/**
 * @file Version.h
 * @author Pierre Le Bodic
 * @date lundi 12 décembre
 */

#include <string>
#include "ExceptionDeVersion.h"

#ifndef _VERSION_H_
#define _VERSION_H_

namespace gestionnaireDeVersions {
   using std::string;
   class SystemeDeVersionnage;

/**
 * Encode la version d'un objet quelconque, selon une certaine méthode de
 * versionnage. Cette classe s'articule autour de deux attributs : une 
 * chaîne de caractères représentant la version (par ex 1.10.5 ou 
 * 20111212) ainsi qu'un système de versionnage qui peut "lire" la chaîne
 * de caractères comme une version.
 * A chaque changement et lorsque c'est possible, les méthodes  s'assurent que 
 * le couple version/versionnage est valide.
 */
class Version {
   private:
      ///La version de l'objet, par exemple 1.1 ou 1.10.2a
      string version;
      ///Décrit la manière de laquelle la version doit être lue.
      const SystemeDeVersionnage *versionnage;
      ///Indique si un système de versionnage a déjà été initialisé.
      bool versionnageConnu;
      ///Indique si la version est connue
      bool versionConnue;
      
   public:
   
      /**
       * Constructeur par défaut. Appelle les constructeurs par défaut
       * des attributs ou les initialise à NULL.
       */
      Version();

      /**
       * Construit une instance avec le système de versionnage
       * donné et la chaîne de caractères donnée.
       * La chaîne de caractères donnée doit bien être valide pour le
       * système de versionnage fourni.
       * @param systeme Le système de versionnage.
       * @param version La chaîne de caractères (ex: 1.0.1).
       * @throw Une exception si la version n'est pas valide pour le
       * versionnage donné.
       */
      Version(const SystemeDeVersionnage* systeme, string version) throw(ExceptionDeVersion);
      
      /**
       * Le destructeur n'a rien à faire.
       */
      virtual ~Version();
      
      /**
       * Permet de renseigner le système de versionnage si l'instance
       * n'en a pas encore.
       * @param systeme Le système de versionnage à affecter à l'instance.
       * @throw Une exception si un système de versionnage est déjà connu
       * ou si la version n'est pas valide pour le système de versionnage.
       */
      void setSystemeDeVersionnage(const SystemeDeVersionnage* systeme) throw(ExceptionDeVersion);
      
      /**
       * Permet de modifier la chaîne de caractères représentant la 
       * version de l'instance. Une chaîne valide doit être fournie.
       * @param version La nouvelle version.
       * @throw Une exception si la version n'est pas valide pour le système de versionnage s'il y en a un.
       */
      void setChaineVersion(string version) throw(ExceptionDeVersion);
      
      /**
       * Indique si l'instance dispose d'un système de versionnage.
       * @return Vrai ssi un système de versionnage est connu.
       */
      bool aUnSystemeDeVersionnage() const;
      
      /**
       * Indique si l'instance dispose d'une version.
       * @return Vrai ssi l'instance a une version.
       */
      bool aUneChaineVersion() const;
      
      /**
       * Retourne le système de versionnage de l'instance.
       * @return Le système de versionnage de l'instance.
       * @throw Une exception si l'instance n'a pas de système de versionnage.
       */
      const SystemeDeVersionnage* getSystemeDeVersionnage() const  throw(ExceptionDeVersion);
      
      /**
       * Retourne la chaîne de caractères représentant la version.
       * @return La chaîne de caractères de la version.
       * @throw Une exception si la version n'est pas définie.
       */
      const string getChaineVersion() const throw(ExceptionDeVersion);
};

}//namespace

#include "SystemeDeVersionnage.h"

#endif // _VERSION_H_
